package org.dromara.hm.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.service.CustomerService;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.helper.DataPermissionHelper;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.hm.domain.HmPaymentAdjustment;
import org.dromara.hm.domain.HmSaleOrder;
import org.dromara.hm.domain.HmStock;
import org.dromara.hm.domain.HmTodoItems;
import org.dromara.hm.domain.bo.HmPaymentAdjustmentBo;
import org.dromara.hm.domain.bo.HmReturnedGiftBo;
import org.dromara.hm.domain.bo.HmSaleOrderBo;
import org.dromara.hm.domain.bo.HmSaleOrderGiftBo;
import org.dromara.hm.domain.bo.HmSaleOrderPickUpBo;
import org.dromara.hm.domain.bo.HmSaleOrderRefundBo;
import org.dromara.hm.domain.bo.HmStockChangeBo;
import org.dromara.hm.domain.bo.HmSupplementaryPickupRecordBo;
import org.dromara.hm.domain.bo.HmTodoItemsBo;
import org.dromara.hm.domain.vo.HmCustomerVo;
import org.dromara.hm.domain.vo.HmPaymentAdjustmentVo;
import org.dromara.hm.domain.vo.HmProductVo;
import org.dromara.hm.domain.vo.saleOrder.HmSaleOrderGiftVo;
import org.dromara.hm.domain.vo.saleOrder.HmSaleOrderPickUpVo;
import org.dromara.hm.domain.vo.saleOrder.HmSaleOrderRefundVo;
import org.dromara.hm.domain.vo.saleOrder.HmSaleOrderVo;
import org.dromara.hm.domain.vo.HmStockVo;
import org.dromara.hm.domain.vo.saleOrder.HmSupplementaryPickupRecordVo;
import org.dromara.hm.domain.vo.saleOrder.OrderItemVo;
import org.dromara.hm.domain.vo.saleOrder.OrderProductQuantities;
import org.dromara.hm.domain.vo.saleOrder.PaymentRecordVo;
import org.dromara.hm.enums.OrderStatus;
import org.dromara.hm.enums.PickUpStatusEnum;
import org.dromara.hm.enums.StockChangeTypeEnum;
import org.dromara.hm.enums.StockTypeEnum;
import org.dromara.hm.enums.ToDoTypeEnum;
import org.dromara.hm.mapper.HmCustomerMapper;
import org.dromara.hm.mapper.HmPaymentAdjustmentMapper;
import org.dromara.hm.mapper.HmProductMapper;
import org.dromara.hm.mapper.saleOrder.HmSaleOrderMapper;
import org.dromara.hm.mapper.HmStockMapper;
import org.dromara.hm.mapper.HmThresholdManagementMapper;
import org.dromara.hm.mapper.HmTodoItemsMapper;
import org.dromara.hm.mapper.StatisticsMapper;
import org.dromara.hm.service.IHmProductService;
import org.dromara.hm.service.IHmSaleOrderGiftService;
import org.dromara.hm.service.IHmSaleOrderService;
import org.dromara.hm.service.IHmStockChangeService;
import org.dromara.hm.service.IHmSupplementaryPickupRecordService;
import org.dromara.hm.service.IHmTodoItemsService;
import org.dromara.hm.service.IHmPaymentAdjustmentService;
import org.dromara.hm.util.OrderProductCalculator;
import org.dromara.system.domain.vo.SysDeptVo;
import org.dromara.system.domain.vo.SysUserVo;
import org.dromara.system.mapper.SysUserMapper;
import org.dromara.system.mapper.SysUserRoleMapper;
import org.dromara.system.service.ISysDeptService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.DoubleStream;

/**
 * 销售订单Service业务层处理
 *
 * @author zy Hu
 * @date 2024-12-15
 */
@RequiredArgsConstructor
@Service
@Primary
public class HmSaleOrderServiceImpl implements IHmSaleOrderService, CustomerService
{

    private final HmSaleOrderMapper baseMapper;

    private final HmProductMapper productMapper;

    private final HmCustomerMapper customerMapper;

    private final HmTodoItemsMapper todoItemsMapper;

    private final StatisticsMapper statisticsMapper;

    private final HmSaleOrderPickUpServiceImpl hmSaleOrderPickUpService;

    private final IHmTodoItemsService todoItemsService;

    @Autowired
    private HmThresholdManagementMapper hmThresholdManagementMapper;

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private HmStockMapper hmStockMapper;

    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;

    private final IHmSaleOrderGiftService saleOrderGiftService;

    private final IHmStockChangeService stockChangeService;

    @Autowired
    private HmSaleOrderRefundServiceImpl hmSaleOrderRefundServiceImpl;

    private final ISysDeptService deptService;

    private final IHmProductService hmProductService; // 注入新的产品Service

    private final IHmSupplementaryPickupRecordService supplementaryPickupRecordService;

    private final OrderProductCalculator orderProductCalculator; // 注入 OrderProductCalculator

    @Autowired
    private HmPaymentAdjustmentMapper paymentAdjustmentMapper; // 直接注入Mapper避免循环依赖

    /**
     * 查询销售订单
     *
     * @param saleId 主键
     *
     * @return 销售订单
     */
    @Override
    public HmSaleOrderVo queryById(Long saleId)
    {
        // 1. 从数据库获取原始订单基本信息
        HmSaleOrderVo hmSaleOrderVo = baseMapper.selectVoById(saleId);

        if (hmSaleOrderVo == null) {
            return null; // 订单不存在则直接返回null
        }

        // 2. 填充 JSON 中存在但 HmSaleOrderVo 中缺失或需要转换的单值字段
        // orderNo: 假设订单号就是 saleId 的字符串形式
        hmSaleOrderVo.setOrderNo(String.valueOf(hmSaleOrderVo.getSaleId()));

        // customerPhone: 从 HmCustomer 实体中获取客户电话
        HmCustomerVo customerVo = customerMapper.selectVoById(hmSaleOrderVo.getCustomerId());
        if (customerVo != null) {
            hmSaleOrderVo.setCustomerPhone(customerVo.getPhone());
            // customerName 字段已通过 @Translation 自动填充，无需手动设置
        }

        // 3. 更新计算字段 (已提货、剩余提货、已回款、剩余回款等)
        // 这一步会填充 hmSaleOrderVo 的 pickUpNum, surplusNum, returnAmount, refundSurplusNum
        updateSaleOrderCalculatedFields(saleId, hmSaleOrderVo);

        // 4. 填充所有列表数据

        // 获取所有与该订单相关的提货/回款记录 (用于后续计算 OrderItemList 中每个产品的已提/剩余数量)
        HmSaleOrderPickUpBo hmSaleOrderPickUpBo = new HmSaleOrderPickUpBo();
        hmSaleOrderPickUpBo.setSaleOrderId(saleId);
        hmSaleOrderPickUpBo.setStatus(PickUpStatusEnum.NORMAL.getCode()); // 只考虑正常状态的记录
        List<HmSaleOrderPickUpVo> allPickupAndPaymentRecords = hmSaleOrderPickUpService.queryList(hmSaleOrderPickUpBo);


        // orderItemList: 订单项列表 (包含主产品和所有赠品)
        List<OrderItemVo> orderItemVos = new ArrayList<>();

        // a. 添加主产品作为订单项
        OrderItemVo mainOrderItem = new OrderItemVo();
        mainOrderItem.setId(hmSaleOrderVo.getSaleProductId()); // 使用产品ID作为ID
        mainOrderItem.setProductId(hmSaleOrderVo.getSaleProductId());
        mainOrderItem.setProductName(hmSaleOrderVo.getSaleProductName());
        List<String> mainProductTypes = hmProductService.selectProductTypesById(hmSaleOrderVo.getSaleProductId());
        mainOrderItem.setProductType(String.join(",", mainProductTypes)); // 例如 "CP"
        mainOrderItem.setQuantity(hmSaleOrderVo.getSaleNum()); // 销售数量
        mainOrderItem.setTotalAmount(hmSaleOrderVo.getSaleAmount()); // 总金额

        // 计算主产品的已提货和剩余数量
        OrderProductQuantities mainProductQuantities = orderProductCalculator.calculate(hmSaleOrderVo, hmSaleOrderVo.getSaleProductId(), allPickupAndPaymentRecords);
        mainOrderItem.setPickedUpQuantity(mainProductQuantities.getTotalPickedUpQuantity());
        mainOrderItem.setRemainingQuantity(mainProductQuantities.getSurplusQuantity());
        // 假设单价 = 总金额 / 销售数量 (避免除数为0)
        if (hmSaleOrderVo.getSaleNum() != null && hmSaleOrderVo.getSaleNum().doubleValue() > 0) {
            mainOrderItem.setPrice(hmSaleOrderVo.getSaleAmount().divide(hmSaleOrderVo.getSaleNum(), 2, BigDecimal.ROUND_HALF_UP));
        } else {
            mainOrderItem.setPrice(BigDecimal.ZERO);
        }
        orderItemVos.add(mainOrderItem);


        // b. 添加赠品作为订单项
        if ("Y".equals(hmSaleOrderVo.getIsGift())) {
            HmSaleOrderGiftBo hmSaleOrderGiftBo = new HmSaleOrderGiftBo();
            hmSaleOrderGiftBo.setSaleId(saleId);
            List<HmSaleOrderGiftVo> hmSaleOrderGiftVos = saleOrderGiftService.queryList(hmSaleOrderGiftBo);
            hmSaleOrderVo.setGiftList(hmSaleOrderGiftVos); // 设置到 giftList 字段

            for (HmSaleOrderGiftVo giftVo : hmSaleOrderGiftVos) {
                OrderItemVo giftOrderItem = new OrderItemVo();
                giftOrderItem.setId(giftVo.getGiftId()); // 使用赠品记录ID作为ID
                giftOrderItem.setProductId(giftVo.getGiftProductId());
                giftOrderItem.setProductName(giftVo.getGiftProductName());
                giftOrderItem.setProductType("ZP"); // 赠品类型
                giftOrderItem.setQuantity(giftVo.getGiftNum()); // 赠送数量
                giftOrderItem.setPrice(BigDecimal.ZERO); // 赠品价格为0

                // 计算赠品的已提货和剩余数量
                OrderProductQuantities giftQuantities = orderProductCalculator.calculate(hmSaleOrderVo, giftVo.getGiftProductId(), allPickupAndPaymentRecords);
                giftOrderItem.setPickedUpQuantity(giftQuantities.getTotalPickedUpQuantity());
                giftOrderItem.setRemainingQuantity(giftQuantities.getSurplusQuantity()); // 这里的surplusQuantity是针对赠品总数而言的

                giftOrderItem.setTotalAmount(BigDecimal.ZERO); // 赠品总金额为0
                orderItemVos.add(giftOrderItem);
            }
        }
        hmSaleOrderVo.setOrderItemList(orderItemVos); // 设置到 orderItemList 字段


        // 过滤allPickupAndPaymentRecords为 1 的提货数据
        List<HmSaleOrderPickUpVo> saleOrderPickUpList = allPickupAndPaymentRecords.stream().filter(item -> StockTypeEnum.PICK_UP.getCode().equals(item.getPickUpType())).toList();
        hmSaleOrderVo.setHmSaleOrderPickUpVoList(saleOrderPickUpList);


        // supplementaryPickupRecordList: 补充提货记录列表
        HmSupplementaryPickupRecordBo supplementaryBo = new HmSupplementaryPickupRecordBo();
        supplementaryBo.setOriginalSaleId(saleId);
        List<HmSupplementaryPickupRecordVo> supplementaryPickupRecordVos = supplementaryPickupRecordService.queryList(supplementaryBo);
        hmSaleOrderVo.setSupplementaryPickupRecordList(supplementaryPickupRecordVos);


        // refundRecordList: 退款记录列表
        HmSaleOrderRefundBo refundBo = new HmSaleOrderRefundBo();
        refundBo.setSaleId(String.valueOf(saleId));
        List<HmSaleOrderRefundVo> refundRecordVos = hmSaleOrderRefundServiceImpl.queryList(refundBo);
        hmSaleOrderVo.setRefundRecordList(refundRecordVos);


        // paymentRecordList: 支付记录列表
        List<HmSaleOrderPickUpVo> paymentRecordVos = allPickupAndPaymentRecords.stream().filter(item -> StockTypeEnum.RETURN_MONEY.getCode().equals(item.getPickUpType())).toList();
        List<PaymentRecordVo> paymentRecordList = new ArrayList<>();
        paymentRecordVos.forEach(item -> {
            PaymentRecordVo payment = new PaymentRecordVo();
            payment.setId(item.getPickUpId());
            payment.setPaymentNo(String.valueOf(item.getPickUpId()));
            payment.setAmount(item.getPickUpNum());
            payment.setMethod(item.getMethod());
            payment.setCreateTime(item.getPickUpTime());
            paymentRecordList.add(payment);
        });

        hmSaleOrderVo.setPaymentRecordList(paymentRecordList);


        return hmSaleOrderVo;
    }

    /**
     * 计算数据
     *
     * @param saleId
     * @param hmSaleOrderVo
     */
    public void CalculateData(Long saleId, HmSaleOrderVo hmSaleOrderVo)
    {
        HmSaleOrderPickUpBo hmSaleOrderPickUpBo = new HmSaleOrderPickUpBo();
        hmSaleOrderPickUpBo.setSaleOrderId(saleId);
        List<HmSaleOrderPickUpVo> hmSaleOrderPickUpVos = hmSaleOrderPickUpService.queryList(hmSaleOrderPickUpBo);

        // 获取产品类型信息
        Boolean isCommercialProduct = hmProductService.isCommercialProduct(hmSaleOrderVo.getSaleProductId());
        Boolean isGiftProduct = hmProductService.isGiftProduct(hmSaleOrderVo.getSaleProductId());

        // 2. 过滤 pickUpType 为 1 的提货记录数据,计算商品总提货数量
        // 提货数量现在根据产品是商品还是赠品来区分
        double pickUpSum = 0;
        if (Boolean.TRUE.equals(isCommercialProduct)) { // 如果是商品产品，统计商品提货
            pickUpSum = hmSaleOrderPickUpVos.stream()
                .filter(hmSaleOrderPickUpVo -> OrderStatus.PICK_UP.getCode().equals(hmSaleOrderPickUpVo.getPickUpType())) // 提货
                .filter(hmSaleOrderPickUpVo -> hmSaleOrderPickUpVo.getSaleProductId().equals(hmSaleOrderVo.getSaleProductId()))
                .filter(hmSaleOrderPickUpVo -> !hmSaleOrderPickUpVo.getStatus().equals(PickUpStatusEnum.CANCEL.getCode()))
                .flatMapToDouble(hmSaleOrderPickUpVo -> DoubleStream.of(hmSaleOrderPickUpVo.getPickUpNum().doubleValue())).sum();
        } else if (Boolean.TRUE.equals(isGiftProduct)) { // 如果是赠品产品，统计赠品提货
            pickUpSum = hmSaleOrderPickUpVos.stream()
                .filter(hmSaleOrderPickUpVo -> OrderStatus.PICK_UP.getCode().equals(hmSaleOrderPickUpVo.getPickUpType())) // 提货
                .filter(hmSaleOrderPickUpVo -> hmSaleOrderPickUpVo.getSaleProductId().equals(hmSaleOrderVo.getGiftProductId())) // 假设赠品提货记录关联的是赠品ID
                .filter(hmSaleOrderPickUpVo -> !hmSaleOrderPickUpVo.getStatus().equals(PickUpStatusEnum.CANCEL.getCode()))
                .flatMapToDouble(hmSaleOrderPickUpVo -> DoubleStream.of(hmSaleOrderPickUpVo.getPickUpNum().doubleValue())).sum();
        }


        // 3. 总提货退货数量
        double pickUpReturnNum = hmSaleOrderPickUpVos.stream()
            .filter(hmSaleOrderPickUpVo -> OrderStatus.PICK_UP.getCode().equals(hmSaleOrderPickUpVo.getPickUpType())) // 总提货退货数量
            .filter(hmSaleOrderPickUpVo -> hmSaleOrderPickUpVo.getSaleProductId().equals(hmSaleOrderVo.getSaleProductId())) // 假设退货也按 saleProductId 关联
            .filter(hmSaleOrderPickUpVo -> hmSaleOrderPickUpVo.getStatus().equals(PickUpStatusEnum.RETURN.getCode()))
            .flatMapToDouble(hmSaleOrderPickUpVo -> DoubleStream.of(hmSaleOrderPickUpVo.getReturnNum().doubleValue())).sum();
        pickUpSum = pickUpSum - pickUpReturnNum; // 总提货数量

        // 4. 过滤pickUpType为0的回款记录数据,计算商品已回款金额
        double surplusNum = hmSaleOrderPickUpVos.stream().filter(hmSaleOrderPickUpVo -> "0".equals(hmSaleOrderPickUpVo.getPickUpType()))
            .filter(hmSaleOrderPickUpVo -> !hmSaleOrderPickUpVo.getStatus().equals(PickUpStatusEnum.CANCEL.getCode()))
            .flatMapToDouble(hmSaleOrderPickUpVo -> DoubleStream.of(hmSaleOrderPickUpVo.getPickUpNum().doubleValue())).sum();

        //5. 总回款退款金额
        double surplusReturnNum = hmSaleOrderPickUpVos.stream().filter(hmSaleOrderPickUpVo -> "0".equals(hmSaleOrderPickUpVo.getPickUpType()))
            .filter(hmSaleOrderPickUpVo -> hmSaleOrderPickUpVo.getStatus().equals(PickUpStatusEnum.RETURN.getCode()))
            .flatMapToDouble(hmSaleOrderPickUpVo -> DoubleStream.of(hmSaleOrderPickUpVo.getReturnNum().doubleValue())).sum();
        surplusNum = surplusNum - surplusReturnNum; // 总回款金额
        // 6. 查询退货数量
        HmSaleOrderRefundBo hmSaleOrderRefundBo = new HmSaleOrderRefundBo();
        hmSaleOrderRefundBo.setSaleId(saleId + "");
        hmSaleOrderRefundBo.setSaleProductId(hmSaleOrderVo.getSaleProductId() + "");
        List<HmSaleOrderRefundVo> hmSaleOrderRefundVos = hmSaleOrderRefundServiceImpl.queryList(hmSaleOrderRefundBo);
        BigDecimal refundNum = Optional.ofNullable(hmSaleOrderRefundVos).orElse(new ArrayList<>()).stream().map(HmSaleOrderRefundVo::getReturnNum)
            .reduce(BigDecimal.ZERO, BigDecimal::add);
        // 总退款金额
        BigDecimal refundAmount = Optional.ofNullable(hmSaleOrderRefundVos).orElse(new ArrayList<>()).stream().map(HmSaleOrderRefundVo::getRefundAmount)
            .reduce(BigDecimal.ZERO, BigDecimal::add);

        hmSaleOrderVo.setReturnAmount(Convert.toBigDecimal(surplusNum, new BigDecimal(0))); // 已回款金额
        hmSaleOrderVo.setPickUpNum(Convert.toBigDecimal(pickUpSum, new BigDecimal(0))); // 已提货数量
        hmSaleOrderVo.setSurplusNum(hmSaleOrderVo.getSaleNum().subtract(refundAmount).subtract(hmSaleOrderVo.getPickUpNum())); // 剩余提货数量
        // 总销售金额 - 总退款金额 - 总已回款金额
        hmSaleOrderVo.setRefundSurplusNum(hmSaleOrderVo.getSaleAmount().subtract(refundAmount).subtract(Convert.toBigDecimal(surplusNum))); // 剩余未回款金额
        hmSaleOrderVo.setHmSaleOrderPickUpVoList(hmSaleOrderPickUpVos); // 提货回款记录详情
    }

    /**
     * 分页查询销售订单列表
     *
     * @param bo        查询条件
     * @param pageQuery 分页参数
     * 1909227392352825345
     *
     * @return 销售订单分页列表
     */
    @Override
    public TableDataInfo<HmSaleOrderVo> queryPageList(HmSaleOrderBo bo, PageQuery pageQuery)
    {
        IPage<HmSaleOrderVo> result;
        if(bo.getParams().containsKey("refundStartTime") &&  bo.getParams().containsKey("refundEndTime")){
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            try {
                bo.setRefundStartTime(dateFormat.parse(bo.getParams().get("refundStartTime").toString()));
                bo.setRefundEndTime(dateFormat.parse(bo.getParams().get("refundEndTime").toString()));
            } catch (ParseException e) {
                throw new RuntimeException("日期格式解析异常，请使用 yyyy-MM-dd 格式", e);
            }
        }

        // 判断是否存在自定义的回款时间范围或剩余提货量范围
        boolean hasCustomCriteria = (bo.getRefundStartTime() != null && bo.getRefundEndTime() != null) ||
            bo.getMinSurplusNum() != null || bo.getMaxSurplusNum() != null ||
            bo.getMinRefundAmount() != null || bo.getMaxRefundAmount() != null;

        if (hasCustomCriteria) {
            // 如果存在自定义条件，则调用自定义的Mapper方法
            result = baseMapper.selectVoPageByCustomCriteria(pageQuery.build(), bo);
        } else {
            // 否则，使用默认的查询构建器
            LambdaQueryWrapper<HmSaleOrder> lqw = buildQueryWrapper(bo);
            result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        }

        List<HmSaleOrderVo> hmSaleOrderVos = result.getRecords();
        if (!hmSaleOrderVos.isEmpty())
        {
            getPickUpInfo(hmSaleOrderVos);

        }
        // 赠品处理

        return TableDataInfo.build(result);
    }

    /**
     * 查询符合条件的销售订单列表
     *
     * @param bo 查询条件
     *
     * @return 销售订单列表
     */
    @Override
    public List<HmSaleOrderVo> queryList(HmSaleOrderBo bo)
    {
        LambdaQueryWrapper<HmSaleOrder> lqw = buildQueryWrapper(bo);
        List<HmSaleOrderVo> hmSaleOrderVos = baseMapper.selectVoList(lqw);
        if (!hmSaleOrderVos.isEmpty())
        {
            getPickUpInfo(hmSaleOrderVos);
        }

        return hmSaleOrderVos;
    }

    private void getPickUpInfo(List<HmSaleOrderVo> hmSaleOrderVos)
    {
        hmSaleOrderVos.forEach(hmSaleOrderVo ->
        {
            // 2. 赠品处理
            // 若存在赠品则获取赠品数据
            if ("Y".equals(hmSaleOrderVo.getIsGift()))
            {
                HmSaleOrderGiftBo hmSaleOrderGiftBo = new HmSaleOrderGiftBo();
                hmSaleOrderGiftBo.setSaleId(hmSaleOrderVo.getSaleId());

                List<HmSaleOrderGiftVo> hmSaleOrderGiftVos = saleOrderGiftService.queryList(hmSaleOrderGiftBo);
                if (hmSaleOrderGiftVos.size() > 0)
                {
                    hmSaleOrderVo.setGiftList(hmSaleOrderGiftVos);
                }
            }
            // 1. 根据销售订单Id查询所有的销售订单提货记录并更新计算字段
            updateSaleOrderCalculatedFields(hmSaleOrderVo.getSaleId(), hmSaleOrderVo); // 调用新的公共方法

        });
    }

    /**
     * 更新销售订单的提货和回款相关计算字段。
     * 此方法将替代原有的 private CalculateData 方法。
     *
     * @param saleId 销售订单ID
     * @param hmSaleOrderVo 销售订单VO
     */
    public void updateSaleOrderCalculatedFields(Long saleId, HmSaleOrderVo hmSaleOrderVo) {
        // 1. 获取所有与该订单相关的提货/回款记录 (由 SaleOrderService 负责获取)
        HmSaleOrderPickUpBo hmSaleOrderPickUpBo = new HmSaleOrderPickUpBo();
        hmSaleOrderPickUpBo.setSaleOrderId(saleId);
        hmSaleOrderPickUpBo.setStatus(PickUpStatusEnum.NORMAL.getCode()); // 只考虑正常状态的记录
        List<HmSaleOrderPickUpVo> hmSaleOrderPickUpVos = hmSaleOrderPickUpService.queryList(hmSaleOrderPickUpBo); // 调用提货Service获取

        // 使用 OrderProductCalculator 进行计算
        OrderProductQuantities quantities = orderProductCalculator.calculate(hmSaleOrderVo, hmSaleOrderVo.getSaleProductId(), hmSaleOrderPickUpVos);

        hmSaleOrderVo.setPickUpNum(quantities.getTotalPickedUpQuantity()); // 已提货数量 (包含补充提货)
        hmSaleOrderVo.setSurplusNum(quantities.getSurplusQuantity()); // 剩余提货数量

        hmSaleOrderVo.setReturnAmount(quantities.getActualReceivedAmount()); // 已回款金额

        // 2. 计算实时未回款金额：原始未回款金额 - 已批准的回款调整金额
        BigDecimal originalUnpaid = quantities.getRefundSurplusAmount(); // 原始未回款金额

        // 查询该订单所有已批准的回款调整记录
        BigDecimal approvedAdjustmentAmount = getApprovedAdjustmentAmount(saleId);

        // 实时未回款金额 = 原始未回款 - 调整金额
        BigDecimal realTimeUnpaid = originalUnpaid.subtract(approvedAdjustmentAmount);

        hmSaleOrderVo.setRefundSurplusNum(realTimeUnpaid); // 剩余未回款金额（考虑调整后）

        // 额外信息：记录调整金额（可选，用于前端展示）
        if (approvedAdjustmentAmount.compareTo(BigDecimal.ZERO) > 0) {
            hmSaleOrderVo.setRemark(hmSaleOrderVo.getRemark() != null
                ? hmSaleOrderVo.getRemark() + "；已调整：" + approvedAdjustmentAmount
                : "已调整：" + approvedAdjustmentAmount);
        }

        // 提货回款记录详情 (这部分仍然需要单独获取，因为 OrderProductCalculator 只计算数量，不返回详情列表)
        // hmSaleOrderVo.setHmSaleOrderPickUpVoList(hmSaleOrderPickUpVos); // 这一行在 getPickUpInfo 中设置更合适
    }

    /**
     * 获取该订单所有已批准的回款调整金额总和
     *
     * @param saleId 销售订单ID
     * @return 已批准的调整金额总和
     */
    private BigDecimal getApprovedAdjustmentAmount(Long saleId) {
        // 直接使用Mapper查询该订单所有已批准的回款调整记录（避免循环依赖）
        LambdaQueryWrapper<org.dromara.hm.domain.HmPaymentAdjustment> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(org.dromara.hm.domain.HmPaymentAdjustment::getSaleId, saleId);
        wrapper.eq(org.dromara.hm.domain.HmPaymentAdjustment::getStatus,
            org.dromara.hm.enums.PaymentAdjustmentStatusEnum.APPROVED.getCode());

        List<org.dromara.hm.domain.HmPaymentAdjustment> approvedAdjustments
            = paymentAdjustmentMapper.selectList(wrapper);

        // 累加所有调整金额
        BigDecimal totalAdjustment = BigDecimal.ZERO;
        if (approvedAdjustments != null && !approvedAdjustments.isEmpty()) {
            for (org.dromara.hm.domain.HmPaymentAdjustment adjustment : approvedAdjustments) {
                totalAdjustment = totalAdjustment.add(adjustment.getAdjustmentAmount());
            }
        }

        return totalAdjustment;
    }

    private LambdaQueryWrapper<HmSaleOrder> buildQueryWrapper(HmSaleOrderBo bo)
    {
        if (bo.getSaleOrderTime() != null)
        {
            LocalDateTime localDateTime = DateUtil.toLocalDateTime(bo.getSaleOrderTime());
            String format = localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
            bo.setOrderTime(format);
        }
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<HmSaleOrder> lqw = Wrappers.lambdaQuery();
        lqw.like(bo.getSaleId() != null, HmSaleOrder::getSaleId, bo.getSaleId());
        lqw.eq(bo.getSaleProductId() != null, HmSaleOrder::getSaleProductId, bo.getSaleProductId());
        lqw.eq(bo.getSaleNum() != null, HmSaleOrder::getSaleNum, bo.getSaleNum());
        lqw.eq(bo.getSaleDept() != null, HmSaleOrder::getSaleDept, bo.getSaleDept());
        lqw.eq(bo.getSaleUser() != null, HmSaleOrder::getSaleUser, bo.getSaleUser());
        lqw.eq(bo.getCustomerId() != null, HmSaleOrder::getCustomerId, bo.getCustomerId());
        lqw.like(bo.getSaleOrderTime() != null, HmSaleOrder::getSaleOrderTime, bo.getOrderTime());
        lqw.between(params.containsKey("beginTime") && params.containsKey("endTime"), HmSaleOrder::getSaleOrderTime, params.get("beginTime"), params.get("endTime"));
        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), HmSaleOrder::getStatus, bo.getStatus());
        lqw.orderByDesc(HmSaleOrder::getSaleOrderTime).orderByDesc(HmSaleOrder::getSaleId);
        return lqw;
    }

    /**
     * 新增销售订单
     *
     * @param bo 销售订单
     *
     * @return 是否新增成功
     */
    @Transactional
    @Override
    public Boolean insertByBo(HmSaleOrderBo bo)
    {
        HmSaleOrder add = MapstructUtils.convert(bo, HmSaleOrder.class);
        // 设置订单编号为当前年月日时分秒+随机数
        String orderNumber = DateUtil.format(new Date(), "yyyyMMddHHmmss") + (int) (Math.random() * 1000);
        add.setSaleId(Long.parseLong(orderNumber));
        add.setSaleUserName(LoginHelper.getLoginUser().getDeptName());
        // 查询该订单号是否存在
        LambdaQueryWrapper<HmSaleOrder> lqw = Wrappers.lambdaQuery();
        lqw.eq(HmSaleOrder::getSaleId, add.getSaleId());
        HmSaleOrder hmSaleOrder = baseMapper.selectOne(lqw);
        while (hmSaleOrder != null)
        {
            orderNumber = DateUtil.format(new Date(), "yyyyMMddHHmmss") + (int) (Math.random() * 1000);
            add.setSaleId(Long.parseLong(orderNumber));
            hmSaleOrder = baseMapper.selectOne(lqw);
        }
        // 新增产品使⽤时间
        HmProductVo hmProductVo = hmProductService.queryById(bo.getSaleProductId()); // 通过Service获取产品信息
        //根据产品的使⽤规格和数量预估产品的使⽤时间;
        if (ObjectUtil.isNotEmpty(hmProductVo) && Boolean.TRUE.equals(hmProductVo.getIsCommercialProduct()) // 只有商品产品才计算使用时间
            && ObjectUtil.isNotEmpty(hmProductVo.getSpecifications()) && ObjectUtil.isNotEmpty(hmProductVo.getRemark()))
        {
            Integer specifications = extractNumber(hmProductVo.getSpecifications());//规格
            Integer remark = extractNumber(hmProductVo.getRemark());//服用量
            BigDecimal saleNum = bo.getSaleNum();//)购买数量
            Integer day = saleNum.multiply(BigDecimal.valueOf(specifications)).divide(BigDecimal.valueOf(remark), RoundingMode.HALF_UP).intValue();
            HmCustomerVo hmCustomerVo = customerMapper.selectVoById(bo.getCustomerId());
            if (null != hmCustomerVo && null != hmCustomerVo.getFamilyId())
            {
                day = saleNum.multiply(BigDecimal.valueOf(specifications)).divide(BigDecimal.valueOf(2 * remark), RoundingMode.HALF_UP).intValue(); // 家庭成员共享，使用量翻倍
            }
            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.DAY_OF_YEAR, -day);// 减少天数，因为是预计使用完毕时间
            Date tenDaysLater = calendar.getTime();// 获取减少天数后的 Date 对象
            bo.setUseTime(tenDaysLater);
        }

        boolean flag = baseMapper.insert(add) > 0;
        // 新增一条待办回访提醒
        //validEntityBeforeSave(bo); // 暂时注释，如果需要，请确保其逻辑正确且不与新逻辑冲突
        // 处理赠品
        if ("Y".equals(bo.getIsGift()))
        {
            List<HmSaleOrderGiftBo> hmSaleOrderGiftBos = new ArrayList<>();
            // 确保 giftProductId1, giftNum1 不为 null 且产品是赠品类型才添加
            if (bo.getGiftProductId1() != null && bo.getGiftNum1() != null && hmProductService.isGiftProduct(Long.parseLong(bo.getGiftProductId1()))) {
                HmSaleOrderGiftBo giftBo = new HmSaleOrderGiftBo();
                giftBo.setSaleId(add.getSaleId());
                giftBo.setGiftProductId(bo.getGiftProductId1());
                giftBo.setGiftNum(bo.getGiftNum1());
                hmSaleOrderGiftBos.add(giftBo);
            }
            if (bo.getGiftProductId2() != null && bo.getGiftNum2() != null && hmProductService.isGiftProduct(Long.parseLong(bo.getGiftProductId2())))
            {
                HmSaleOrderGiftBo giftBo2 = new HmSaleOrderGiftBo();
                giftBo2.setSaleId(add.getSaleId());
                giftBo2.setGiftProductId(bo.getGiftProductId2());
                giftBo2.setGiftNum(bo.getGiftNum2());
                hmSaleOrderGiftBos.add(giftBo2);
            }
            if (bo.getGiftProductId3() != null && bo.getGiftNum3() != null && hmProductService.isGiftProduct(Long.parseLong(bo.getGiftProductId3())))
            {
                HmSaleOrderGiftBo giftBo3 = new HmSaleOrderGiftBo();
                giftBo3.setSaleId(add.getSaleId());
                giftBo3.setGiftProductId(bo.getGiftProductId3());
                giftBo3.setGiftNum(bo.getGiftNum3());
                hmSaleOrderGiftBos.add(giftBo3);
            }
            if (bo.getGiftProductId4() != null && bo.getGiftNum4() != null && hmProductService.isGiftProduct(Long.parseLong(bo.getGiftProductId4())))
            {
                HmSaleOrderGiftBo giftBo4 = new HmSaleOrderGiftBo();
                giftBo4.setSaleId(add.getSaleId());
                giftBo4.setGiftProductId(bo.getGiftProductId4());
                giftBo4.setGiftNum(bo.getGiftNum4());
                hmSaleOrderGiftBos.add(giftBo4);
            }
            if (bo.getGiftProductId5() != null && bo.getGiftNum5() != null && hmProductService.isGiftProduct(Long.parseLong(bo.getGiftProductId5())))
            {
                HmSaleOrderGiftBo giftBo5 = new HmSaleOrderGiftBo();
                giftBo5.setSaleId(add.getSaleId());
                giftBo5.setGiftProductId(bo.getGiftProductId5());
                giftBo5.setGiftNum(bo.getGiftNum5());
                hmSaleOrderGiftBos.add(giftBo5);
            }
            // 保存赠品
            Optional.ofNullable(hmSaleOrderGiftBos).ifPresent(hmSaleOrderGiftBos1 -> hmSaleOrderGiftBos1.forEach(hmSaleOrderGiftBo ->
            {
                hmSaleOrderGiftBo.setStatus("0"); // 默认未提货
                saleOrderGiftService.insertByBo(hmSaleOrderGiftBo);
            }));
        }
        if (flag)
        {
            bo.setSaleId(add.getSaleId());
        }
        return flag;
    }

    /**
     * 从规格字符串中提取数字。
     *
     * @param spec 规格字符串，例如 "560g/桶"
     *
     * @return 提取出的数字
     */
    private static int extractNumber(String spec)
    {
        try
        {
            // 使用正则表达式匹配数字
            String digits = spec.replaceAll("[^\\d]", "");
            return Integer.parseInt(digits);
        }
        catch (Exception e)
        {
            throw new RuntimeException("请检查产品规格是否填写且格式正确,正确格式例如 56g/桶");
        }

    }

    /**
     * 修改销售订单
     *
     * @param bo 销售订单
     *
     * @return 是否修改成功
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateByBo(HmSaleOrderBo bo)
    {
        HmSaleOrder update = MapstructUtils.convert(bo, HmSaleOrder.class);
        boolean b = baseMapper.updateById(update) > 0;

        // --- 赠品修改逻辑开始 ---
        if ("Y".equals(bo.getIsGift())) {
            // 1. 查询当前订单已有的赠品列表
            HmSaleOrderGiftBo queryExistingGiftBo = new HmSaleOrderGiftBo();
            queryExistingGiftBo.setSaleId(update.getSaleId());
            List<HmSaleOrderGiftVo> existingGiftVos = saleOrderGiftService.queryList(queryExistingGiftBo);

            // 将现有赠品转换为 Map，以便通过 giftProductId 快速查找
            Map<Long, HmSaleOrderGiftVo> existingGiftMap = existingGiftVos.stream()
                .filter(g -> g.getGiftProductId() != null)
                .collect(Collectors.toMap(HmSaleOrderGiftVo::getGiftProductId, g -> g));

            // 收集传入的赠品列表
            List<HmSaleOrderGiftBo> incomingGiftBos = new ArrayList<>();
            // 确保 giftProductId1, giftNum1 不为 null 且产品是赠品类型才添加
            if (bo.getGiftProductId1() != null && bo.getGiftNum1() != null && hmProductService.isGiftProduct(Long.parseLong(bo.getGiftProductId1()))) {
                HmSaleOrderGiftBo giftBo = new HmSaleOrderGiftBo();
                giftBo.setSaleId(update.getSaleId());
                giftBo.setGiftProductId(bo.getGiftProductId1());
                giftBo.setGiftNum(bo.getGiftNum1());
                incomingGiftBos.add(giftBo);
            }
            if (bo.getGiftProductId2() != null && bo.getGiftNum2() != null && hmProductService.isGiftProduct(Long.parseLong(bo.getGiftProductId2()))) {
                HmSaleOrderGiftBo giftBo = new HmSaleOrderGiftBo();
                giftBo.setSaleId(update.getSaleId());
                giftBo.setGiftProductId(bo.getGiftProductId2());
                giftBo.setGiftNum(bo.getGiftNum2());
                incomingGiftBos.add(giftBo);
            }
            if (bo.getGiftProductId3() != null && bo.getGiftNum3() != null && hmProductService.isGiftProduct(Long.parseLong(bo.getGiftProductId3()))) {
                HmSaleOrderGiftBo giftBo = new HmSaleOrderGiftBo();
                giftBo.setSaleId(update.getSaleId());
                giftBo.setGiftProductId(bo.getGiftProductId3());
                giftBo.setGiftNum(bo.getGiftNum3());
                incomingGiftBos.add(giftBo);
            }
            if (bo.getGiftProductId4() != null && bo.getGiftNum4() != null && hmProductService.isGiftProduct(Long.parseLong(bo.getGiftProductId4()))) {
                HmSaleOrderGiftBo giftBo = new HmSaleOrderGiftBo();
                giftBo.setSaleId(update.getSaleId());
                giftBo.setGiftProductId(bo.getGiftProductId4());
                giftBo.setGiftNum(bo.getGiftNum4());
                incomingGiftBos.add(giftBo);
            }
            if (bo.getGiftProductId5() != null && bo.getGiftNum5() != null && hmProductService.isGiftProduct(Long.parseLong(bo.getGiftProductId5()))) {
                HmSaleOrderGiftBo giftBo = new HmSaleOrderGiftBo();
                giftBo.setSaleId(update.getSaleId());
                giftBo.setGiftProductId(bo.getGiftProductId5());
                giftBo.setGiftNum(bo.getGiftNum5());
                incomingGiftBos.add(giftBo);
            }


            // 2. 遍历传入的赠品列表，进行更新或新增
            for (HmSaleOrderGiftBo incomingGiftBo : incomingGiftBos) {
                Long incomingGiftProductId = Long.parseLong(incomingGiftBo.getGiftProductId());
                if (existingGiftMap.containsKey(incomingGiftProductId)) {
                    // 赠品已存在，进行更新操作
                    HmSaleOrderGiftVo existingGiftVo = existingGiftMap.get(incomingGiftProductId);
                    HmSaleOrderGiftBo updateGiftBo = new HmSaleOrderGiftBo();
                    BeanUtils.copyProperties(existingGiftVo, updateGiftBo); // 复制现有数据
                    updateGiftBo.setGiftId(existingGiftVo.getGiftId()); // 设置主键
                    updateGiftBo.setGiftNum(incomingGiftBo.getGiftNum()); // 更新数量
                    updateGiftBo.setStatus("0"); // 确保状态正常
                    saleOrderGiftService.updateByBo(updateGiftBo);
                    existingGiftMap.remove(incomingGiftProductId); // 从map中移除，剩余的将是被删除的
                } else {
                    // 赠品不存在，进行新增操作
                    incomingGiftBo.setStatus("0"); // 默认未提货状态
                    saleOrderGiftService.insertByBo(incomingGiftBo);
                }
            }

            // 3. 处理被移除的赠品（在现有列表中，但传入列表中不存在的）
            // existingGiftMap 中剩余的元素就是需要删除的赠品
            if (!existingGiftMap.isEmpty()) {
                List<Long> giftIdsToDelete = existingGiftMap.values().stream()
                    .map(HmSaleOrderGiftVo::getGiftId)
                    .collect(Collectors.toList());
                saleOrderGiftService.deleteWithValidByIds(giftIdsToDelete, true);
            }
        } else {
            // 如果 isGift 为 "N"，表示订单不再有赠品，删除所有现有赠品
            HmSaleOrderGiftBo queryExistingGiftBo = new HmSaleOrderGiftBo();
            queryExistingGiftBo.setSaleId(update.getSaleId());
            List<HmSaleOrderGiftVo> existingGiftVos = saleOrderGiftService.queryList(queryExistingGiftBo);
            if (!existingGiftVos.isEmpty()) {
                List<Long> giftIdsToDelete = existingGiftVos.stream()
                    .map(HmSaleOrderGiftVo::getGiftId)
                    .collect(Collectors.toList());
                saleOrderGiftService.deleteWithValidByIds(giftIdsToDelete, true);
            }
        }
        // --- 赠品修改逻辑结束 ---

        return b;
    }

    /**
     * 校验并批量删除销售订单信息
     *
     * @param ids     待删除的主键集合
     * @param isValid 是否进行有效性校验
     *
     * @return 是否删除成功
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid)
    {
        if (isValid)
        {
            // 删除订单,查询是否有回款和提货记录,有回款记录同步删除,有提货记录则将已经提货的数量返还给对应仓库,并增加一条type = 2的订单回填数据
            for (Long id : ids)
            {
                HmSaleOrderPickUpBo hmSaleOrderPickUpBo = new HmSaleOrderPickUpBo();
                hmSaleOrderPickUpBo.setSaleOrderId(id);
                hmSaleOrderPickUpBo.setStatus("0"); // 过滤已经提货作废的记录
                List<HmSaleOrderPickUpVo> hmSaleOrderPickUpVos = hmSaleOrderPickUpService.queryList(hmSaleOrderPickUpBo);
                Optional.ofNullable(hmSaleOrderPickUpVos).orElse(new ArrayList<>()).forEach(hmSaleOrderPickUpVo ->
                {
                    // 获取产品类型信息
                    Boolean isCommercialProduct = hmProductService.isCommercialProduct(hmSaleOrderPickUpVo.getSaleProductId());
                    Boolean isGiftProduct = hmProductService.isGiftProduct(hmSaleOrderPickUpVo.getSaleProductId());

                    // 只有是商品产品或赠品产品且有提货记录才进行库存回填
                    if (OrderStatus.PICK_UP.getCode().equals(hmSaleOrderPickUpVo.getPickUpType()) &&
                        (Boolean.TRUE.equals(isCommercialProduct) || Boolean.TRUE.equals(isGiftProduct)))
                    {
                        // 提货
                        // 查询对应产品和销售店铺的库存记录
                        HmSaleOrderVo hmSaleOrderVo = baseMapper.selectVoById(hmSaleOrderPickUpVo.getSaleOrderId());
                        if (hmSaleOrderVo == null) {
                            // 订单可能已被删除，跳过此提货记录的处理
                            return;
                        }
                        HmStockVo hmStockVo = hmStockMapper.selectVoOne(Wrappers.<HmStock>lambdaQuery()
                            .eq(HmStock::getStockProductId, hmSaleOrderPickUpVo.getSaleProductId())
                            .eq(HmStock::getProductDept, hmSaleOrderVo.getSaleDept()));
                        if (hmStockVo == null) {
                            // 库存记录不存在，可能数据异常，记录日志或跳过
                            return;
                        }
                        int i = Math.abs(hmSaleOrderPickUpVo.getPickUpNum().toBigInteger().intValue());
                        hmStockVo.setStockNum(hmStockVo.getStockNum().add(BigDecimal.valueOf(i)));
                        hmStockMapper.updateById(MapstructUtils.convert(hmStockVo, HmStock.class));

                        // 新增库存变更历史记录
                        HmStockChangeBo hmStockChangeBo = new HmStockChangeBo();
                        hmStockChangeBo.setStockId(hmStockVo.getStockId()); // 库存id
                        hmStockChangeBo.setChangeType(StockChangeTypeEnum.DEL_ORDER.getCode()); // 变更类型
                        hmStockChangeBo.setChangeInfo(StockChangeTypeEnum.DEL_ORDER.getDescription()); // 变更详情
                        hmStockChangeBo.setChangeNum(BigDecimal.valueOf(i));// 变更数量
                        hmStockChangeBo.setChangeTime(new Date()); // 变更时间
                        hmStockChangeBo.setProductId(String.valueOf(hmSaleOrderPickUpVo.getSaleProductId())); // 变更商品id
                        hmStockChangeBo.setOrderId(hmSaleOrderPickUpVo.getSaleOrderId());
                        hmStockChangeBo.setOperatorId(hmSaleOrderVo.getCustomerId().toString()); // 操作人id
                        HmCustomerVo hmCustomerVo = customerMapper.selectVoById(hmSaleOrderVo.getCustomerId());
                        hmStockChangeBo.setRemark(String.format("订单[%s]删除,客户[%s]", hmSaleOrderPickUpVo.getSaleOrderId(), hmCustomerVo != null ? hmCustomerVo.getCustomerName() : "未知客户"));
                        stockChangeService.insertByBo(hmStockChangeBo);
                    }
                    else if ("0".equals(hmSaleOrderPickUpVo.getPickUpType()))
                    {
                        // 回款
                        HmSaleOrderPickUpBo hmSaleOrderPickUpBo1 = new HmSaleOrderPickUpBo();
                        BeanUtils.copyProperties(hmSaleOrderPickUpVo, hmSaleOrderPickUpBo1);
                        hmSaleOrderPickUpBo1.setDelFlag(1L);
                        hmSaleOrderPickUpBo1.setStatus(PickUpStatusEnum.CANCEL.getCode());
                        hmSaleOrderPickUpService.updateByBo(hmSaleOrderPickUpBo1);
                    }
                });
            }
        }
        return baseMapper.deleteByIds(ids) > 0;
    }

    @Override
    public String selectCustomerNameById(Long customerId)
    {
        HmCustomerVo hmCustomerVo = DataPermissionHelper.ignore(() ->
        {
            return customerMapper.selectVoById(customerId);
        });

        if (hmCustomerVo != null)
        {
            return hmCustomerVo.getCustomerName();
        }
        return null;
    }

    /**
     * 订单退货
     *
     * @param requestDto 退货请求DTO
     * @return 处理结果
     */
    @Override
    @Transactional // 确保整个退货流程是原子性的
    public int orderReturns(HmSaleOrderRefundBo requestDto)
    {
        System.out.println("开始处理退货退款申请，订单ID: " + requestDto.getSaleId());
        // 获取当前订单
        HmSaleOrderVo saleOrder = baseMapper.selectVoById(Long.valueOf(requestDto.getSaleId()));
        if (saleOrder == null) {
            throw new ServiceException("订单不存在，无法进行退货退款操作。");
        }

        BigDecimal finalRefundAmount = BigDecimal.ZERO;
        Boolean isAmount = Boolean.FALSE;
        Boolean isReturn = Boolean.FALSE;

        // 1. 处理退款逻辑
        finalRefundAmount = Optional.ofNullable(requestDto.getRefundAmount()).orElse(BigDecimal.ZERO);
        if (finalRefundAmount.compareTo(BigDecimal.ZERO) < 0)
        {
            throw new IllegalArgumentException("退款金额不能为负数。");
        }
        if (Boolean.TRUE.equals(requestDto.getApplyForRefund()) && finalRefundAmount.compareTo(BigDecimal.ZERO) > 0)
        {
            isAmount = Boolean.TRUE;
            BigDecimal TotalRefund = finalRefundAmount.add(Optional.ofNullable(saleOrder.getRefundAmount()).orElse(BigDecimal.ZERO));
            saleOrder.setRefundAmount(TotalRefund);

            if (saleOrder.getSaleAmount().compareTo(TotalRefund) == 0)
            {
                saleOrder.setRefundStatus(2); // 退款状态为全部退款

            }
            else if (saleOrder.getSaleAmount().compareTo(TotalRefund) > 0)
            {
                saleOrder.setRefundStatus(1); // 退款状态为部分
            }
            else
            {
                throw new ServiceException("退款金额大于订单金额！"); // 使用 ServiceException
            }
            System.out.println("退款逻辑处理完成 ");
        }

        // 2. 处理主产品退货
        if (StringUtils.isNotBlank(requestDto.getSaleProductId())) // 确保 saleProductId 不为空
        {
            // 校验是否为商品产品
            if (!hmProductService.isCommercialProduct(Long.parseLong(requestDto.getSaleProductId()))) {
                throw new ServiceException("退货产品ID: " + requestDto.getSaleProductId() + " 不是商品产品，无法进行主产品退货。");
            }

            // 确保 pickedQty 和 unpickedQty 不为 null
            BigDecimal mainProductPickedQty = Optional.ofNullable(requestDto.getMainProductReturnPickedQty()).orElse(BigDecimal.ZERO);
            BigDecimal mainProductUnpickedQty = Optional.ofNullable(requestDto.getMainProductReturnUnpickedQty()).orElse(BigDecimal.ZERO);
            BigDecimal totalMainProductReturnQty = mainProductPickedQty.add(mainProductUnpickedQty);



            if (totalMainProductReturnQty.compareTo(BigDecimal.ZERO) > 0)
            {
                isReturn = Boolean.TRUE;
                System.out.println("处理主产品退货: " + requestDto.getSaleProductId() + ", 已提退: " + mainProductPickedQty + ", 未提退: " + mainProductUnpickedQty);

                // 订单总退货数量 本次退货数量 + 订单历史已退货数量
                BigDecimal currentReturnTotalNum = Optional.ofNullable(saleOrder.getReturnTotalNum()).orElse(BigDecimal.ZERO);
                BigDecimal newTotalNum = currentReturnTotalNum.add(totalMainProductReturnQty);

                if (saleOrder.getSaleNum().compareTo(newTotalNum) >= 0)
                {
                    saleOrder.setReturnTotalNum(newTotalNum);
                    if (saleOrder.getSaleNum().compareTo(newTotalNum) == 0) {
                        saleOrder.setReturnStatus(3); // 全部退货
                    } else {
                        saleOrder.setReturnStatus(1); // 部分退货
                    }
                }
                else
                {
                    throw new ServiceException("退货数量大于订单销售数量！"); // 使用 ServiceException
                }
                requestDto.setReturnNum(totalMainProductReturnQty); // 本次退货总数量 (已提+未提)
                requestDto.setActualReturnToStockNum(mainProductPickedQty); // 实际回填库存数量 (只回填已提货部分)
            }
        }

        // 3. 插入主产品退款退货明细 (如果发生退款或退货)
        if (isAmount || isReturn)
        {
            requestDto.setProcessorId(LoginHelper.getLoginUser().getUserId().toString());
            requestDto.setApplyTime(new Date());
            requestDto.setProductType("CP"); // 主产品退货退款
            hmSaleOrderRefundServiceImpl.insertByBo(requestDto);

            // 如果有已提货退货，则更新提货单状态
            if (isReturn && Optional.ofNullable(requestDto.getMainProductReturnPickedQty()).orElse(BigDecimal.ZERO).compareTo(BigDecimal.ZERO) > 0)
            {
                hmSaleOrderPickUpService.processReturnLogic(requestDto, OrderStatus.PICK_UP.getCode());
            }
            // 如果有退款，则更新回款单状态
            if (isAmount) {
                hmSaleOrderPickUpService.processReturnLogic(requestDto, OrderStatus.RETURN_MONEY.getCode());
            }

            // 生成待办事项 (只有在有实际回填库存数量时才生成入库待办)
            if (isReturn && Optional.ofNullable(requestDto.getActualReturnToStockNum()).orElse(BigDecimal.ZERO).compareTo(BigDecimal.ZERO) > 0) {
                createTodoItem(requestDto, saleOrder);
            }

            System.out.println("主退款记录已创建。申请退款: " + requestDto.getApplyForRefund() + ", 金额: " + finalRefundAmount);
            // 更新订单的总退货数量与总退款金额
            saleOrder.setLastReturnTime(new Date());
            HmSaleOrder updateSaleOrder = new HmSaleOrder();
            BeanUtils.copyProperties(saleOrder, updateSaleOrder);
            baseMapper.updateById(updateSaleOrder);
        }

        // 4. 处理赠品退货
        if (requestDto.getReturnedGifts() != null && !requestDto.getReturnedGifts().isEmpty())
        {
            for (HmReturnedGiftBo giftDto : requestDto.getReturnedGifts())
            {
                // 校验是否为赠品产品
                if (!hmProductService.isGiftProduct(Long.parseLong(giftDto.getGiftProductId()))) {
                    System.err.println("赠品产品ID: " + giftDto.getGiftProductId() + " 不是赠品产品，跳过处理。");
                    continue; // 跳过非赠品产品的处理
                }

                // 获取当前订单当前赠品数据
                HmSaleOrderGiftBo hmSaleOrderGiftBo = new HmSaleOrderGiftBo();
                hmSaleOrderGiftBo.setSaleId(Long.parseLong(requestDto.getSaleId()));
                hmSaleOrderGiftBo.setGiftProductId(giftDto.getGiftProductId());
                List<HmSaleOrderGiftVo> hmSaleOrderGiftVos = saleOrderGiftService.queryList(hmSaleOrderGiftBo);
                if (hmSaleOrderGiftVos.isEmpty()) {
                    System.err.println("未找到赠品ID: " + giftDto.getGiftProductId() + " 对应的赠品记录，跳过处理。");
                    continue; // 赠品不存在，跳过当前赠品处理
                }
                HmSaleOrderGiftVo hmSaleOrderGiftVo = hmSaleOrderGiftVos.get(0);

                // 确保 pickedQty 和 unpickedQty 不为 null
                BigDecimal giftReturnPickedQty = Optional.ofNullable(giftDto.getGiftReturnPickedQty()).orElse(BigDecimal.ZERO);
                BigDecimal giftReturnUnpickedQty = Optional.ofNullable(giftDto.getGiftReturnUnpickedQty()).orElse(BigDecimal.ZERO);
                BigDecimal totalGiftReturnQty = giftReturnPickedQty.add(giftReturnUnpickedQty);



                if (totalGiftReturnQty.compareTo(BigDecimal.ZERO) > 0)
                {
                    System.out.println("处理赠品退货: " + giftDto.getGiftProductId() + ", 已提退: " + giftReturnPickedQty + ", 未提退: " + giftReturnUnpickedQty);
                    // 赠品退货退款记录
                    HmSaleOrderRefundBo giftRefundRequestDto = new HmSaleOrderRefundBo();
                    giftRefundRequestDto.setProcessorId(LoginHelper.getLoginUser().getUserId().toString()); // 退货处理人
                    giftRefundRequestDto.setSaleId(requestDto.getSaleId()); // 销售订单ID
                    giftRefundRequestDto.setApplyTime(new Date()); // 退货时间
                    giftRefundRequestDto.setProductType("ZP"); // 赠品退货
                    giftRefundRequestDto.setReturnNum(totalGiftReturnQty); // 退货数量 (已提+未提)
                    giftRefundRequestDto.setActualReturnToStockNum(giftReturnPickedQty); // 实际回填库存数量 (只回填已提货部分)
                    giftRefundRequestDto.setSaleProductId(giftDto.getGiftProductId()); // 退货产品id
                    giftRefundRequestDto.setReasonCode("OTHER");
                    giftRefundRequestDto.setRefundType(2); // 假设赠品退货类型为2 (全部退货)
                    giftRefundRequestDto.setDescription("赠品退货");
                    hmSaleOrderRefundServiceImpl.insertByBo(giftRefundRequestDto);

                    if (giftReturnPickedQty.compareTo(BigDecimal.ZERO) > 0)
                    {
                        // 处理已提货更新提货单
                        HmSaleOrderRefundBo requestDto1 = new HmSaleOrderRefundBo();
                        requestDto1.setSaleId(requestDto.getSaleId());
                        requestDto1.setSaleProductId(giftDto.getGiftProductId());
                        requestDto1.setMainProductReturnPickedQty(giftReturnPickedQty); // 这里使用 MainProductReturnPickedQty 传递已提数量
                        requestDto1.setRefundId(giftRefundRequestDto.getRefundId());
                        hmSaleOrderPickUpService.processReturnLogic(requestDto1, OrderStatus.PICK_UP.getCode());
                    }

                    // 更新赠品表中的退货数量
                    hmSaleOrderGiftVo.setGiftRefundableNum(Optional.ofNullable(hmSaleOrderGiftVo.getGiftRefundableNum()).orElse(BigDecimal.ZERO).add(totalGiftReturnQty)); // 累计退货总数量
                    hmSaleOrderGiftVo.setPickedQty(Optional.ofNullable(hmSaleOrderGiftVo.getPickedQty()).orElse(BigDecimal.ZERO).add(giftReturnPickedQty)); // 从已提货的退货数量
                    hmSaleOrderGiftVo.setUnpickedQty(Optional.ofNullable(hmSaleOrderGiftVo.getUnpickedQty()).orElse(BigDecimal.ZERO).add(giftReturnUnpickedQty)); // 从未提货的退货数量
                    HmSaleOrderGiftBo updateBo = new HmSaleOrderGiftBo();
                    BeanUtils.copyProperties(hmSaleOrderGiftVo, updateBo);
                    saleOrderGiftService.updateByBo(updateBo);

                    // 生成待办事项 (只有在有实际回填库存数量时才生成入库待办)
                    if (Optional.ofNullable(giftRefundRequestDto.getActualReturnToStockNum()).orElse(BigDecimal.ZERO).compareTo(BigDecimal.ZERO) > 0) {
                        createTodoItem(giftRefundRequestDto, saleOrder);
                    }

                    System.out.println("赠品 " + giftDto.getGiftProductId() + " 退货处理完成");
                    // 更新订单的退货状态 (如果主产品和赠品都退了，则状态可能更复杂，这里简化处理)
                    if ("1".equals(saleOrder.getReturnStatus()) || "3".equals(saleOrder.getReturnStatus()))
                    {
                        saleOrder.setReturnStatus(3); // 如果主产品已部分退货或全部退货，则保持全部退货状态
                    }
                    else if ("0".equals(saleOrder.getReturnStatus()))
                    {
                        saleOrder.setReturnStatus(2); // 如果之前无退货，则设置为赠品退货（部分退货）
                    }
                    HmSaleOrder updateSaleOrder = new HmSaleOrder();
                    BeanUtils.copyProperties(saleOrder, updateSaleOrder);
                    baseMapper.updateById(updateSaleOrder);
                }
            }
        }

        System.out.println("退货退款申请处理流程结束。");
        return 1;
    }

    private void createTodoItem(HmSaleOrderRefundBo requestDto, HmSaleOrderVo saleOrder)
    {
        List<SysUserVo> sysUserVos = new ArrayList<>();
        List<SysUserVo> sysUserVos1 = deptService.selectUserListByDeptId(saleOrder.getSaleDept());
        if (ObjectUtil.isNotEmpty(sysUserVos1))
        {
            // 说明为多店店长长
            sysUserVos = sysUserVos1;
        }
        else
        {
            // 单店长
            sysUserVos = deptService.selectUserListByDeptIdAndRoleId(saleOrder.getSaleDept(), 1869282439378976770L);// 角色对应为店长
        }

        //TODO 此处为创建待办逻辑
        SysDeptVo sysDeptVoStart = deptService.selectDeptById(saleOrder.getSaleDept());
        HmTodoItems hmTodoItemsBo = new HmTodoItems();
        hmTodoItemsBo.setTodoType(ToDoTypeEnum.SALE_ORDER_REFUND.getCode()); // 退款退货提醒
        hmTodoItemsBo.setTodoDesc(String.format("订单[%s]退货,申请商品/赠品入库，退货数量：%s", saleOrder.getSaleId(),requestDto.getReturnNum()));
        hmTodoItemsBo.setCreateType("1"); // 系统生成
        hmTodoItemsBo.setReturnOrderId(Long.parseLong(requestDto.getRefundId()));

        // 设置提交人信息（当前登录人）
        hmTodoItemsBo.setSubmitterId(LoginHelper.getUserId());
        hmTodoItemsBo.setSubmitterName(LoginHelper.getUsername());

        if (ObjectUtil.isNotEmpty(sysUserVos))
        {
            hmTodoItemsBo.setTodoPersonId(sysUserVos.get(0).getUserId());
            hmTodoItemsBo.setTodoPersonName(sysUserVos.get(0).getNickName());
            hmTodoItemsBo.setTodoStockDept(saleOrder.getSaleDept());
            // 设置审核人
            hmTodoItemsBo.setApproverId(sysUserVos.get(0).getUserId());
            hmTodoItemsBo.setApproverName(sysUserVos.get(0).getNickName());

        }
        else
        {
            // 默认给超级管理员
            hmTodoItemsBo.setTodoPersonId(1L);
            hmTodoItemsBo.setTodoPersonName("超级管理员");
            hmTodoItemsBo.setRemark("尚未找到对应店铺的店长");
            // 设置审核人为超级管理员
            hmTodoItemsBo.setApproverId(1L);
            hmTodoItemsBo.setApproverName("超级管理员");
        }

        todoItemsMapper.insert(hmTodoItemsBo);
    }

    // 离职人员订单迁移
    @Override
    public void updateSaleOrderAndTodo(List<Long> customerIds, Long effectiveNewStaffId, String effectiveNewStaffName, Long effectiveNewStoreId, String effectiveNewStoreName, String operatorUsername, Date now)
    {
        baseMapper.updateSaleOrderOwnerByCustomerIds(customerIds, effectiveNewStaffId, effectiveNewStaffName, effectiveNewStoreId, effectiveNewStoreName, operatorUsername, now);
    }

    @Override
    public List<HmSaleOrder> selectUnfinishedOrdersByCustomerIds(List<Long> actualCustomerIdsToTransfer)
    {
        return baseMapper.selectUnfinishedOrdersByCustomerIds(actualCustomerIdsToTransfer);
    }
}
